﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Unijovem.Domain;
using Unijovem.Domain.Biblia;
using Unijovem.UI.Models;

namespace Unijovem.UI.Controllers
{
    public class LeituraBiblicaController : ControllerBase<LeituraBiblicaModel, LeituraBiblica>
    {
        public override ActionResult Index()
        {
            return View();
        }

        public ActionResult PreencherMes(int mes)
        {
            var models =
                new LeituraBiblica().SelectAllActive<LeituraBiblica>().Where(
                    m => m.Dia > (31*mes) && m.Dia <= (31*(mes + 1))).
                    Select(m => new LeituraBiblicaModel
                                    {
                                        Dia = m.Dia,
                                        Id = m.Id,
                                        Ordem = m.Ordem,
                                        Versiculo = m.Versiculo,
                                        QuantidadeComentarios = m.LeituraBiblicaComentarios.Count,
                                        QuantidadeUsuarios = m.LeituraBiblicaUsuarios.Count,
                                        Usuarios = m.LeituraBiblicaUsuarios.Select(p =>
                                                new PessoaModel
                                                    {
                                                        Id = p.Usuario.Pessoas.First().Id,
                                                        NomeCompleto = p.Usuario.Pessoas.First().NomeCompleto,
                                                    }).ToList()
                                    }).ToList();
          
            return Json(new { success = true, html =  GetControlData("~/Views/LeituraBiblica/VisualizarMes.cshtml", models)});
        }

        public enum Versao
        {
            Aramaic_NTPeshitta_peshitta = 0,
            English_AmericanKingJamesVersion_akjv = 1,
            English_AmericanStandardVersion_asv = 2,
            English_DouayRheims_douayrheims = 3,
            English_KingJamesVersion_kjv = 4,
            English_WorldEnglishBible_web = 5,
            English_YoungsLiteralTranslation_ylt = 6,
            French_Darby_darby = 7,
            French_LouisSegond1910_ls1910 = 8,
            French_Martin1744_martin = 9,
            French_Ostervald1996revision_ostervald = 10,
            German_Elberfelder1871_elberfelder = 11,
            German_Elberfelder1905_elberfelder1905 = 12,
            German_Luther1545_luther1545 = 13,
            German_Luther1912_luther1912 = 14,
            German_Schlachter1951_schlachter = 15,
            GreekNT_ByzantineMajorityText2000_byzantine = 16,
            GreekNT_TextusReceptus15501894_textusreceptus = 17,
            GreekNT_Tischendorf8thEd_tischendorf = 18,
            GreekNT_WestcottHortUBS4variants_westcott = 19,
            GreekOT_LXXAAccented_lxx = 20,
            GreekOT_LXXAUnaccented_lxxçnoaccents = 21,
            Greek_Modern_moderngreek = 22,
            HebrewOT_AleppoCodex_aleppo = 23,
            HebrewOT_BHSConsonantsVowels_bhs = 24,
            HebrewOT_BHSConsonantsOnly_bhsçnovowels = 25,
            HebrewOT_WestminsterLeningradCodex_wlc = 26,
            HebrewOT_WLCConsonantsVowels_wlc2 = 27,
            HebrewOT_WLCConsonantsOnly_wlcçnovowels = 28,
            Hebrew_Modern_modernhebrew = 29,
            Italian_GiovanniDiodatiBible1649_giovanni = 30,
            Italian_RivedutaBible1927_riveduta = 31,
            Latin_NovaVulgata_newvulgate = 32,
            Latin_VulgataClementina_vulgate = 33,
            Portuguese_AlmeidaAtualizada_almeida = 34,
            Spanish_ReinaValera1909_rv1909 = 35,
            Spanish_ReinaValeraNT1858_rv1858 = 36,
            Spanish_SagradasEscrituras1569_sagradas = 38
        }

        private string TraduzirLivro(string versiculo)
        {
            //Velho Testamento
            versiculo = versiculo.Replace("Gn", "Gen").Replace("Ex", "Exo").Replace("Lv", "Lev");
            versiculo = versiculo.Replace("Nm", "Num").Replace("Js", "Josh");
            versiculo = versiculo.Replace("Jz", "Judg").Replace("Rt", "Rut").Replace("1Sm", "1Sam");
            versiculo = versiculo.Replace("2Sm", "2Sam").Replace("1Rs", "1Kings").Replace("2Rs", "2Kings");
            versiculo = versiculo.Replace("Ne", "Neh").Replace("Et", "Est").Replace("Jó", "Job");
            versiculo = versiculo.Replace("Sl", "Psa").Replace("Pv", "Pro").Replace("Ec", "Ecc");
            versiculo = versiculo.Replace("Ct", "Song").Replace("Is", "Isa").Replace("Jr", "Jer");
            versiculo = versiculo.Replace("Lm", "Lam").Replace("Ez", "Ezek").Replace("Dn", "Dan");
            versiculo = versiculo.Replace("Os", "Hos").Replace("Jl", "Joe").Replace("Am", "Amo");
            versiculo = versiculo.Replace("Ob", "Oba").Replace("Jn", "Jon").Replace("Mq", "Mic");
            versiculo = versiculo.Replace("Na", "Nah").Replace("Hc", "Hab").Replace("Sf", "Zep");
            versiculo = versiculo.Replace("Ag", "Hag").Replace("Zc", "Zec").Replace("Ml", "Mal");

            versiculo = versiculo.Replace("1Cr", "1Chr").Replace("2Cr", "2Chr").Replace("Ed", "Ezra");

            //Novo Testamento
            versiculo = versiculo.Replace("Mt", "Mat").Replace("Mc", "Mar").Replace("Lc", "Luk");
            versiculo = versiculo.Replace("Jo ", "Jn ").Replace("At", "Act").Replace("Rm", "Rom");
            versiculo = versiculo.Replace("1Co", "1Cor").Replace("2Co", "2Cor");
            versiculo = versiculo.Replace("Gl", "Gal").Replace("Ef", "Eph").Replace("Fp", "Phil");
            versiculo = versiculo.Replace("Cl", "Col").Replace("1Ts", "1Thess").Replace("2Ts", "2Thess");
            versiculo = versiculo.Replace("1Tm", "1Tim").Replace("2Tm", "2Tim").Replace("Tt", "Tit");
            versiculo = versiculo.Replace("Fm", "Philemon").Replace("Hb", "Heb").Replace("Tg", "Jam");
            versiculo = versiculo.Replace("1Pe", "1Pet").Replace("2Pe", "2Pet");
            versiculo = versiculo.Replace("1Jo", "1Jn").Replace("2Jo", "2Jn").Replace("3Jo", "3Jn");
            versiculo = versiculo.Replace("Jd", "Jude").Replace("Ap", "Rev");

            return versiculo;
        }

        private string SelecionarTexto(string passagem, Versao versao)
        {
            try
            {
                string ultimoCapitulo = string.Empty;
                var texto = new StringBuilder();

                var itens = SelecionarTextoBiblia(passagem, versao).Range.Itens;

                if (itens.All(i => string.IsNullOrEmpty(i.Text)))
                    return "Texto não disponível para a versão selecionada";

                foreach (var item in itens)
                {
                    if (item.Chapter != ultimoCapitulo)
                    {
                        ultimoCapitulo = item.Chapter;
                        texto.Append("<div class='capitulo'>").Append(passagem.Length < 3 ? passagem : passagem.Substring(0, 3).Trim()).Append(" ");
                        texto.Append(item.Chapter).Append("</div>");
                    }

                    texto.Append("<span class='versiculo'>").Append(item.Verse).Append("</span>");
                    texto.Append(" ").AppendLine(item.Text).AppendLine("<br />");
                }

                return HttpUtility.HtmlDecode(texto.ToString());
            }
            catch
            {
                return "Texto não encontrado.";
            }
        }

        private Bible SelecionarTextoBiblia(string passagem, Versao versao)
        {
            String url = String.Format("http://api.preachingcentral.com/bible.php?passage={0}&version={1}", TraduzirLivro(passagem),
                                       versao.ToString().Split('_')[2].Replace("ç", "-"));

            var client = new WebClient();
            client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0;)"); // pass as Internet Explorer 7.0

            var data = client.OpenRead(url);
            var reader = new StreamReader(data);

            var objeto = Helpers.SerializeHelper.Deserialize<Bible>(reader);

            data.Close();
            reader.Close();

            return objeto;
        }

        public ActionResult Diaria(int? dia = null, int? versao = null)
        {
            try
            {
                var dataInicio = DateTime.Parse(Helpers.ConfigurationHelper.Get(Helpers.ConfigurationHelper.Config.DataInicioLeituraBiblica));
                if (dataInicio > DateTime.Today) return RedirectToAction("Index");

                if (dia == null)
                    dia = (DateTime.Today - dataInicio).Days;

                Versao versaoTexto = versao == null ? Versao.Portuguese_AlmeidaAtualizada_almeida : (Versao)versao;

                var leituras = new LeituraBiblica().SelecionarLeituraDiaria((int)dia);
                var models = new LeituraBiblicaModel().CriarViewModel(leituras);
                var pessoaLogada = PessoaLogada;
                var usuario = pessoaLogada == null ? null : pessoaLogada.Usuario;

                foreach (var leitura in models)
                {
                    bool usuarioLogadoLeuTexto = usuario != null && leitura.LeituraBiblicaUsuarios.Any(l => l.IdUsuario == usuario.Id);

                    leitura.Texto = SelecionarTexto(leitura.Versiculo, versaoTexto);
                    leitura.TextoLeitura = PreencherTextoLeitura(leitura.LeituraBiblicaUsuarios, usuarioLogadoLeuTexto);
                    leitura.UsuarioEstaLogado = usuario != null;
                    leitura.UsuarioLogadoLeuTexto = usuarioLogadoLeuTexto;

                    var usuarios = usuario == null ? leitura.LeituraBiblicaUsuarios : leitura.LeituraBiblicaUsuarios.Where(l => l.IdUsuario != usuario.Id);
                    leitura.Usuarios = new PessoaModel().CriarViewModel(usuarios.Select(l => new Pessoa().SelecionarPessoaPorIdUsuario(l.Usuario.Id))).ToList();

                    //var comentarios = leitura.LeituraBiblicaComentarios.OrderByDescending(d => d.Comentario.Data).Select(d => d.Comentario).ToList();
                    //leitura.PagedComentarios = new PagedList<ComentarioModel>(comentarios, page, 10);
                    var comentarios = leitura.LeituraBiblicaComentarios.OrderByDescending(d => d.Comentario.Data).Select(d =>
                        new ComentarioModel
                        {
                            Data = d.Comentario.Data,
                            Descricao = d.Comentario.Descricao,
                            Id = d.Comentario.Id,
                            IdExterno = d.IdLeituraBiblica,
                            IdPessoa = d.Comentario.IdPessoa,
                            Pessoa = d.Comentario.Pessoa,
                            Tipo = d.Comentario.Tipo
                        }).ToList();
                    WebSession(string.Concat(SessionName.Comentarios, leitura.Id), comentarios);
                }

                return View(models);
            }
            catch 
            {
                return RedirectToAction("Index");
            }
        }

        private string PreencherTextoLeitura(List<LeituraBiblicaUsuarioModel> leituraBiblicaUsuarios, bool usuarioLogadoLeuTexto)
        {
            const string textoLeituraPadrao = " a leitura desta Palavra hoje";

            return !usuarioLogadoLeuTexto
                       ? leituraBiblicaUsuarios.Count == 1
                             ? string.Concat("1 pessoa fez", textoLeituraPadrao)
                             : leituraBiblicaUsuarios.Count > 1
                                   ? string.Concat(leituraBiblicaUsuarios.Count, " pessoas fizeram", textoLeituraPadrao)
                                   : string.Empty
                       : leituraBiblicaUsuarios.Count == 1
                             ? string.Concat("Você fez", textoLeituraPadrao)
                             : leituraBiblicaUsuarios.Count == 2
                                   ? string.Concat("Você e mais ", leituraBiblicaUsuarios.Count - 1, " pessoa fez", textoLeituraPadrao)
                                   : leituraBiblicaUsuarios.Count == 0
                                         ? string.Empty
                                         : string.Concat("Você e mais ", leituraBiblicaUsuarios.Count - 1, " pessoas fizeram", textoLeituraPadrao);
        }

        public ActionResult MarcarLeitura(int idLeitura)
        {
            var leituraUsuario = new LeituraBiblicaUsuario
                              {
                                  Data = DateTime.Now,
                                  IdLeituraBiblica = idLeitura,
                                  IdUsuario = PessoaLogada.IdUsuario
                              };
            leituraUsuario.Save(leituraUsuario);

            var leitura = new LeituraBiblicaModel().CriarViewModel(new LeituraBiblica().SelectById<LeituraBiblica>(idLeitura));

            return Json(new { success = true, textoLeitura = PreencherTextoLeitura(leitura.LeituraBiblicaUsuarios, true) });
        }
    }
}
